/*
 * @(#)GsParseUtils.java
 * 2011-9-24 下午09:52:43
 *
 * Copyright (c) 2018-2028, HangZhou QiYun InfoTech Co.,Ltd. .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.qyxx.platform.gsc;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import com.qyxx.platform.common.utils.httpclient.HttpClientUtils;
import com.qyxx.platform.common.utils.web.struts2.Struts2Utils;
import com.qyxx.platform.gsc.utils.CallBat;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.qyxx.jwp.bean.Button;
import com.qyxx.jwp.bean.DataProperties;
import com.qyxx.jwp.bean.DataSource;
import com.qyxx.jwp.bean.EditPage;
import com.qyxx.jwp.bean.EditProperties;
import com.qyxx.jwp.bean.ExportSystemField;
import com.qyxx.jwp.bean.Extension;
import com.qyxx.jwp.bean.Field;
import com.qyxx.jwp.bean.Form;
import com.qyxx.jwp.bean.Formula;
import com.qyxx.jwp.bean.GsModule;
import com.qyxx.jwp.bean.GsPackage;
import com.qyxx.jwp.bean.Item;
import com.qyxx.jwp.bean.Module;
import com.qyxx.jwp.bean.ModuleProperties;
import com.qyxx.jwp.bean.QueryPage;
import com.qyxx.jwp.bean.Rule;
import com.qyxx.jwp.bean.Sql;
import com.qyxx.jwp.bean.Tab;
import com.qyxx.jwp.bean.Tabs;
import com.qyxx.jwp.datasource.QuerySql;
import com.qyxx.jwp.datasource.TableEntity;
import com.qyxx.jwp.datasource.TableEntitys;
import com.qyxx.jwp.datasource.TeAttr;
import com.qyxx.jwp.menu.Business;
import com.qyxx.jwp.menu.Menu;
import com.qyxx.jwp.menu.Modules;
import com.qyxx.platform.common.definition.Definition.DefinitionEntity;
import com.qyxx.platform.common.freemarker.FreeMarkerEngine;
import com.qyxx.platform.common.freemarker.FreeMarkerExcel;
import com.qyxx.platform.common.freemarker.ModifyArrayDirective;
import com.qyxx.platform.common.freemarker.NewWritableNumberArrayMethod;
import com.qyxx.platform.common.module.dao.HibernateUtils;
import com.qyxx.platform.common.utils.ZipUtils;
import com.qyxx.platform.common.utils.encode.EncodeUtils;
import com.qyxx.platform.common.utils.encode.EncryptAndDecryptUtils;
import com.qyxx.platform.common.utils.encode.JaxbBinder;
import com.qyxx.platform.common.utils.encode.JsonBinder;
import com.qyxx.platform.common.utils.encode.Md5Utils;
import com.qyxx.platform.common.utils.encode.Native2AsciiUtils;
import com.qyxx.platform.common.utils.jxls.JxlsUtils;
import com.qyxx.platform.common.utils.spring.SpringContextHolder;
import com.qyxx.platform.common.utils.template.DefaultFilenameFilter;
import com.qyxx.platform.gsc.cache.SqlCache;
import com.qyxx.platform.gsc.cache.TableEntityCache;
import com.qyxx.platform.gsc.exception.GscException;
import com.qyxx.platform.gsc.utils.Constants;
import com.qyxx.platform.gsc.utils.PathUtils;
import com.qyxx.platform.gsc.utils.SystemParam;
import com.qyxx.platform.gsmng.common.service.GsMngManager;
import com.qyxx.platform.gsmng.common.service.ProcManager;
import com.qyxx.platform.gsmng.common.service.ProcessTraceManager;
import com.qyxx.platform.sysmng.accountmng.service.AuthorityManager;
import com.qyxx.platform.sysmng.dictmng.web.DefinitionCache;
import com.qyxx.platform.sysmng.userconfig.service.BsTableManager;

import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * GS包解析工具类
 * 
 * @author gxj
 * @version 1.0
 * @since 1.6 2011-9-24 下午09:52:43
 */

public class GsParseUtils {
	
	private static final String TOMCAT_RESOURCE_ENTRIES_FIELD = "resourceEntries";

	private static SystemParam sp = SpringContextHolder.getBean("systemParam");
	
	private static AuthorityManager am = SpringContextHolder.getBean("authorityManager");
	
	private static ProcessTraceManager ptm = SpringContextHolder.getBean("processTraceManager");
	
	private static ProcManager pm = SpringContextHolder.getBean("procManager");
	
	private static BsTableManager btm = SpringContextHolder.getBean("bsTableManager");

	//异步服务线程池
	private static  ExecutorService asyncServicePool =  Executors.newFixedThreadPool(20);

	private static Logger logger = LoggerFactory
			.getLogger(GsParseUtils.class);

	/**
	 * 项目根路径（物理地址）
	 */
	private static String appRootPath = SpringContextHolder.getRootPath();
	
	private static String ENCODE = "UTF-8";
	
	private static JsonBinder jsonBinder = JsonBinder.getAlwaysMapper();
	
	/**
	 * 注册Integer null转换器
	 */
	static {
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
	}
	
	/**
	 * 压缩文件，返回文件名
	 * 
	 * @return
	 */
	public static String zipGsFile(String jwpPath) throws IOException {
		String basePath = concat(sp.getUploadFilePath(), Constants.GS_PACKAGE_PATH);
		String configPath = concat(basePath, jwpPath, Constants.PATH_SEPARATOR, Constants.CONFIG_PATH);
		String destFileName = DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMddHHmmssSSS") + Constants.CONFIG_FILE_SUFFIX;
		String destPath = basePath + destFileName;
		ZipUtils.zip(configPath, destPath);
		return destFileName;
	}
	
	/**
	 * 解压GS包文件
	 * 
	 * @param file
	 *            GS包文件
	 */
	public static String unzipGSFile(File file, String filePath) throws IOException {
		//filePath = filePath.endsWith(Constants.PATH_SEPARATOR) ? filePath : filePath + Constants.PATH_SEPARATOR;
		//String fileName = file.getName();
		String zipPath = concat(filePath, Constants.CONFIG_PATH, Constants.MODULE_PATH);
		String jwpPath = file.getAbsolutePath().replace("\\", "/");
		//FileUtils.deleteQuietly(new File(zipPath));
		ZipUtils.unzip(jwpPath, filePath);
		
		
		return zipPath;
	}
	
	
	
	/**
	 * 解析GS包中XML文件
	 * 
	 * @param filePath
	 *            GS包文件夹路径
	 * @throws Exception 
	 */
	public static GsPackage parseGSFile(String filePath) throws Exception {
		GsPackage gsPackage = new GsPackage();
		String  pcXmlPath = concat(filePath,Constants.MODULE_PATH);
		String  appXmlPath = concat(filePath,Constants.GS_PACKAGE_APP_PATH);
		File  pcXmlFile = new File(pcXmlPath);
		File  appXmlFile = new File(appXmlPath);
		Map<String, GsModule> moduleMap = new HashMap<String, GsModule>();
		if (pcXmlFile.isDirectory()) {
			moduleMap.putAll(PathUtils.getGsModuleMap(pcXmlPath));
		}
		if (appXmlFile.isDirectory()) {
			moduleMap.putAll(PathUtils.getGsModuleMap(appXmlPath));
		}
		gsPackage.setModuleMap(moduleMap);
		return gsPackage;
	}

	/**
	 * 处理GS对象，生成jsp文件
	 * 
	 * @param gp
	 * @param jwpPath config所在目录路径
	 * @return
	 */
	public static List<TableEntitys> handleGS(GsPackage gp, String jwpPath) {
		List<TableEntitys> tesList = Lists.newArrayList();
		Map<String, GsModule> mm = gp.getModuleMap();
		if(null!=mm) {
			for(GsModule gm : mm.values()) {
				if(null!=gm) {
					//String gmName = gm.getName().toLowerCase();
					Map<String, Module> gmm = gm.getModuleMap();
					if(null!=gmm) {
						for(Map.Entry<String, Module> gmmr : gmm.entrySet()) {
							String gmrName = gmmr.getKey().toLowerCase();
							Module rt = gmmr.getValue();
							//处理国际化资源属性
							generateI18nProperties(rt, jwpPath);
							//处理表单属性
							TableEntitys tes = handleGsTableItems(rt, gmrName, jwpPath);
							if(null!=tes) {
								//处理规则
								handleRule(tes, rt);
								tesList.add(tes);
							}
						}
					}
				}
			}
		}
		return tesList;
	}
	
	/**
	 * 处理GS对象，生成jsp文件
	 * 针对关联表做些修改
	 * 
	 * @param gp
	 * @param jwpPath config所在目录路径
	 * @return
	 */
	public static List<TableEntitys> handleGSR(GsPackage gp, String jwpPath, Boolean isFullUpdate, List<String> updatedModules) {
		List<TableEntitys> tesList = Lists.newArrayList();
		Map<String, GsModule> mm = gp.getModuleMap();
		if(null != mm) {
			//subEntityMap存放所有被关联模块子表
			Map<String,List<TableEntity>> subEntityMap = new HashMap<String,List<TableEntity>>();
			for(GsModule gm : mm.values()) {
				if(null != gm) {
					Map<String, Module> gmm = gm.getModuleMap();
					if(null!=gmm) {
						for(Map.Entry<String, Module> gmmr : gmm.entrySet()) {
							String gmrName = gmmr.getKey().toLowerCase();
							Module rt = gmmr.getValue();
							//获取关联模块键值RelevanceModule
							String relevance = rt.getModuleProperties().getRelevanceModule();
							if(!StringUtils.isBlank(relevance)) {
								List<TableEntity> subEntitys = Lists.newArrayList();
								for(Form ff : rt.getDataSource().getFormList()) {
									if(!ff.getIsVirtual()) { // 非虚拟表
										//作为主实体的子属性
										TableEntity ote = new TableEntity();
										
										String entityName = rt.getModuleProperties().getKey().toLowerCase() + Constants.NAME_SPLIT_SYMBOL + ff.getKey();
										
										ote.setEntityName(entityName);
										ote.setRefSubEntityName(EncodeUtils.toLowerOrUpperCaseFirstChar(ff.getKey(),true) + Constants.S_SUFFIX);
										ote.setTableName(ff.getTableName());
										//ote.setCaption(ff.getCaption());
										//ote.setEnableExport(ff.getEnableExport());
										//ote.setEnableImport(ff.getEnableImport());
										subEntitys.add(ote);
									}
								}
								
								if(subEntityMap.containsKey(relevance)) {
									subEntityMap.get(relevance).addAll(subEntitys);
								} else {
									subEntityMap.put(relevance, subEntitys);
								}
							}
						}
					}
				}
			}
			for(int count=0; count<2; count++) {
				for(GsModule gm : mm.values()) {
					if(null != gm) {
						Map<String, Module> gmm = gm.getModuleMap();
						if(null!=gmm) {
							for(Map.Entry<String, Module> gmmr : gmm.entrySet()) {
								String gmrName = gmmr.getKey().toLowerCase();
								Module rt = gmmr.getValue();
								//获取关联模块键值RelevanceModule
								String relevance = rt.getModuleProperties().getRelevanceModule();
								//是否存在关联模块，第一次处理普通模块，第二次处理存在关联模块的模块。确保生成数据库子表前关联模块主表已存在
								if(StringUtils.isBlank(relevance) && count==0) {
									if(!isFullUpdate && !btm.checkBsModuleUpdated(rt)) {//增量更新
										continue;
									}
									
									//处理国际化资源属性
									if(ModuleProperties.TYPE_APP.equalsIgnoreCase(rt.getModuleProperties().getType())){
										generateI18nJS(rt, jwpPath);
									}else if(ModuleProperties.TYPE_DICT.equalsIgnoreCase(rt.getModuleProperties().getType())){									
										generateI18nProperties(rt, jwpPath);
										generateI18nJS(rt, jwpPath);
									}else{								
										generateI18nProperties(rt, jwpPath);
									}
									//处理表单属性
									TableEntitys tes = handleGsTableItems(rt, gmrName, jwpPath);
									if(null!=tes) {
										//处理规则
										handleRule(tes, rt);
										//为存在被引用的模块插入所有与之关联的子表
										
										for(TableEntity te : tes.getTableEntity()) {
											if(!te.getIsSubEntity()) {
												String key = gm.getName() + "." + rt.getModuleProperties().getKey();
												if(subEntityMap.containsKey(key)) {
													te.getSubEntitys().addAll(subEntityMap.get(key));
												}
											}
										}
										
										tesList.add(tes);
									}
									
									//保存业务模块信息
									btm.saveBsModule(rt);
									//增量更新加入更新模块名列表
									if(!isFullUpdate) {
										updatedModules.add(rt.getModuleProperties().getKey());
									}
								}
								if(!StringUtils.isBlank(relevance) && count==1) {
									if(!isFullUpdate && !btm.checkBsModuleUpdated(rt)) {//增量更新
										continue;
									}
									
									String[] moduleKey = relevance.split("\\.");
									Module relevanceModule = mm.get(moduleKey[0]).getModuleMap().get(moduleKey[1]);
									String form = null;
									
									String entityName = null;
									
									for(Form f : relevanceModule.getDataSource().getFormList()) {
										if(f.getIsMaster()) {
											rt.getDataSource().getFormList().add(f);
											form = f.getKey();
											entityName = f.getEntityName();
											break;
										}
									}
									for(Tabs t : relevanceModule.getDataSource().getTabsList()) {
										for(Tab tt : t.getTabList()) {
											if(tt.getForm() != null && tt.getForm().equals(form)) {
												for(Tabs tabs : rt.getDataSource().getTabsList()) {
													if(tabs.getRows() == tt.getRows()) {
														tabs.getTabList().add(tt);
														break;
													}
												}
											}
										}
									}
									
									//处理国际化资源属性
									generateI18nProperties(rt, jwpPath);
									//处理表单属性
									TableEntitys tes = handleGsTableItems(rt, gmrName, jwpPath, moduleKey[1]);
									if(null!=tes) {
										//处理规则
										handleRule(tes, rt);
										tesList.add(tes);
									}
									
									for(Form f : relevanceModule.getDataSource().getFormList()) {
										if(f.getIsMaster()) {
											rt.getDataSource().getFormList().remove(f);
											form = f.getKey();
											break;
										}
									}
									for(Tabs t : relevanceModule.getDataSource().getTabsList()) {
										for(Tab tt : t.getTabList()) {
											if(tt.getForm() != null && tt.getForm().equals(form)) {
												for(Tabs tabs : rt.getDataSource().getTabsList()) {
													if(tabs.getRows() == tt.getRows()) {
														tabs.getTabList().remove(tt);
														break;
													}
												}
											}
										}
									}
									
									//保存业务模块信息
									btm.saveBsModule(rt);
									//增量更新加入更新模块名列表
									if(!isFullUpdate) {
										updatedModules.add(rt.getModuleProperties().getKey());
									}
									
								}
								
							}
						}
					}
				}
			}
		}
		return tesList;
	}
	
	/**
	 * 生成hibernate文件及entity文件
	 * 
	 * @param tesList
	 * @param jwpPath
	 */
	public static void handleTableEntitys(List<TableEntitys> tesList, String jwpPath) {
		//生成hibernate xml文件及实体配置文件（用于应用重新初始化后加载），加入实体缓存
		List<String> hbmXmlPathList = Lists.newArrayList();
		for(TableEntitys tes : tesList) {
			if(null!=tes.getTableEntity() && !tes.getTableEntity().isEmpty()) {
				String type = tes.getModuleType();
				for(TableEntity te : tes.getTableEntity()) {
					//生成Hibernate hbm文件，排除子定义表单与虚拟实体
					if(!ModuleProperties.TYPE_FORM.equalsIgnoreCase(type) && !te.getIsVirtual()){
						String xmlPath = generateHbmXml(te, jwpPath);
						hbmXmlPathList.add(xmlPath);
					}
					TableEntityCache.getInstance().put(te.getEntityName(), te);
				}
			}
			if(null!=tes.getQuerySql() && !tes.getQuerySql().isEmpty()) {
				for(QuerySql qs : tes.getQuerySql()) {
					SqlCache.getInstance().put(qs.getKey(), qs, tes.getModuleType());
				}
			}
			TableEntityCache.getInstance().putModuleName(tes.getName(), tes.getDisplayName());
			//生成TableEntitys xml配置文件，供系统重启时自动加载使用
			generateTableEntitysXml(tes, jwpPath);
		}
		//动态加载Hbm文件
		HibernateUtils.updateHibernateCfg(hbmXmlPathList, true);
	}
	
	/**
	 * 处理规则，将规则存入TableEntitys对象
	 * 
	 * @param tes
	 * @param module
	 */
	private static void handleRule(TableEntitys tes, Module module) {
		if(null!=module) {
			List<Rule> ruleList = module.getRuleList();
			if(null!=ruleList && !ruleList.isEmpty()) {
				for(Rule rule : ruleList) {
					if(Rule.TYPE_SQL.equalsIgnoreCase(rule.getType())) {
						//处理sql规则
						if(null!=rule.getSql()) {
							QuerySql qs = new QuerySql();
							qs.setKey(Constants.RULE_SUFFIX + Constants.NAME_SPLIT_SYMBOL + module.getModuleProperties().getKey().toLowerCase() 
									+ Constants.NAME_SPLIT_SYMBOL + rule.getKey());
							qs.setSql(rule.getSql());
							tes.getQuerySql().add(qs);
						}
					} else if(Rule.TYPE_PROC.equalsIgnoreCase(rule.getType())) {
						//处理存过规则
						if(null!=rule.getSql() && StringUtils.isNotBlank(rule.getSql().getContent())) {
							QuerySql qs = new QuerySql();
							qs.setKey(Constants.RULE_SUFFIX + Constants.NAME_SPLIT_SYMBOL + module.getModuleProperties().getKey().toLowerCase() 
									+ Constants.NAME_SPLIT_SYMBOL + rule.getKey());
							qs.setSql(rule.getSql());
							tes.getQuerySql().add(qs);
							//创建存储过程
							pm.createProcedure(rule.getSql().getContent());
						}
					}
				}
			}
		}
	}
	
	/**
	 * 处理模块实体
	 * 
	 * @param rt
	 * @param packageName
	 */
	private static TableEntitys handleGsTableItems(Module rt, String packageName, String jwpPath) {
		if(null!=rt) {
			DataSource gds = rt.getDataSource();
			if(null!=gds) {
				List<Form> tiList = gds.getFormList();
				if(null!=tiList && !tiList.isEmpty()) {
					//Sql缓存
					List<QuerySql> sqlList = Lists.newArrayList();
					TableEntitys tes = new TableEntitys();
					tes.setName(packageName);
					tes.setDisplayName(rt.getModuleProperties().getCaption());
					tes.setModuleType(rt.getModuleProperties().getType());
					String masterEntityName = "";
					String refEntityName = "";
					for(Form ti : tiList) {
						String tiName = ti.getKey();
						//将表属性key首字母转小写
						ti.setLcKey(EncodeUtils.toLowerOrUpperCaseFirstChar(tiName, true));
						String entityName = packageName + Constants.NAME_SPLIT_SYMBOL + tiName;
						//设置实体名称
						ti.setEntityName(entityName);
						/*List<Query> queryList = ti.getQueryList();
						if(null!=queryList && !queryList.isEmpty()) {
							for(Query ep:queryList) {
								if (null!=ep) {
									Formula fm = ep.getFormula();
									if(null!=fm && Formula.TYPE_SQL == fm.getType()) {
										QuerySql qs = new QuerySql();
										String key = Constants.QUERY_SUFFIX + Constants.NAME_SPLIT_SYMBOL + entityName + Constants.NAME_SPLIT_SYMBOL + ep.getKey();
										qs.setKey(key);
										qs.setSql(fm.getSql());
										sqlList.add(qs);
									}
								}
							}
						}*/
						
						TableEntity te = handleGsTable(ti, entityName, sqlList);
						if(null!=te) { 
							te.setModuleType(rt.getModuleProperties().getType()); //设置模块类型
							if(!te.getIsSubEntity()) {
								//主实体
								masterEntityName = te.getEntityName();
								refEntityName = te.getName();
								
								//设置模块主实体名称
								rt.setEntityName(masterEntityName);
							}
							tes.getTableEntity().add(te);
						}
					}
					List<TableEntity> subEntitys = Lists.newArrayList();
					TableEntity masterTe = null;
					for(TableEntity te : tes.getTableEntity()) {
						if(te.getIsSubEntity()) {
							if(!te.getIsVirtual()) { // 非虚拟表
								te.setRefEntityName(EncodeUtils.toLowerOrUpperCaseFirstChar(refEntityName,true));
								te.setMasterEntityName(masterEntityName);
								
								//作为主实体的子属性
								TableEntity ote = new TableEntity();
								ote.setEntityName(te.getEntityName());
								ote.setRefSubEntityName(EncodeUtils.toLowerOrUpperCaseFirstChar(te.getName(),true) + Constants.S_SUFFIX);
								ote.setTableName(te.getTableName());
								ote.setCaption(te.getCaption());
								ote.setEnableExport(te.getEnableExport());
								ote.setEnableImport(te.getEnableImport());
								subEntitys.add(ote);
							}
						} else {
							masterTe = te;
						}
					}
					if(null!=masterTe) {
						masterTe.setSubEntitys(subEntitys);
						//生成JSP文件
						generateJsp(rt, jwpPath, packageName, masterTe.getName());
						//生成导入导出模板文件
						generateExcelTemplate(rt, jwpPath, packageName, masterTe);
					}
					tes.setQuerySql(sqlList);
					return tes;
				} else {
					return null;
				}
			} else {
				return null;
			}
		} else {
			return null;
		}
	}
	
	/**
	 * 处理模块实体
	 * 
	 * @param rt
	 * @param packageName
	 */
	private static TableEntitys handleGsTableItems(Module rt, String packageName, String jwpPath, String moduleKey) {
		if(null!=rt) {
			DataSource gds = rt.getDataSource();
			if(null!=gds) {
				List<Form> tiList = gds.getFormList();
				if(null!=tiList && !tiList.isEmpty()) {
					//Sql缓存
					List<QuerySql> sqlList = Lists.newArrayList();
					TableEntitys tes = new TableEntitys();
					tes.setName(packageName);
					tes.setDisplayName(rt.getModuleProperties().getCaption());
					tes.setModuleType(rt.getModuleProperties().getType());
					String masterEntityName = "";
					String refEntityName = "";
					TableEntity masterTe = null;
					for(Form ti : tiList) {
						String tiName = ti.getKey();
						//将表属性key首字母转小写
						ti.setLcKey(EncodeUtils.toLowerOrUpperCaseFirstChar(tiName, true));
						
						String entityName = null;
						if(ti.getIsMaster()) {
							entityName = moduleKey.toLowerCase() + Constants.NAME_SPLIT_SYMBOL + tiName;
						} else {
							entityName = packageName + Constants.NAME_SPLIT_SYMBOL + tiName;
						}
						
						//设置实体名称
						ti.setEntityName(entityName);
						
						TableEntity te = handleGsTable(ti, entityName, sqlList);
						if(null!=te) { 
							te.setModuleType(rt.getModuleProperties().getType()); //设置模块类型
							if(!te.getIsSubEntity()) {
								//主实体
								masterEntityName = packageName + Constants.NAME_SPLIT_SYMBOL + tiName;
								refEntityName = te.getName();
								
								//设置模块主实体名称
								rt.setEntityName(masterEntityName);
								
								masterEntityName = te.getEntityName();
							}
							
							if(StringUtils.isBlank(rt.getModuleProperties().getRelevanceModule()) || !ti.getIsMaster()) {
								tes.getTableEntity().add(te);
							} else {
								masterTe = te;
							}
						}
						
					}
					List<TableEntity> subEntitys = Lists.newArrayList();
					
					for(TableEntity te : tes.getTableEntity()) {
						if(te.getIsSubEntity()) {
							if(!te.getIsVirtual()) { // 非虚拟表
								te.setRefEntityName(EncodeUtils.toLowerOrUpperCaseFirstChar(refEntityName,true));
								te.setMasterEntityName(masterEntityName);
								
								//作为主实体的子属性
								TableEntity ote = new TableEntity();
								ote.setEntityName(te.getEntityName());
								ote.setRefSubEntityName(EncodeUtils.toLowerOrUpperCaseFirstChar(te.getName(),true) + Constants.S_SUFFIX);
								ote.setTableName(te.getTableName());
								ote.setCaption(te.getCaption());
								ote.setEnableExport(te.getEnableExport());
								ote.setEnableImport(te.getEnableImport());
								subEntitys.add(ote);
							}
						} else {
							masterTe = te;
						}
					}
					if(null!=masterTe) {
						masterTe.setSubEntitys(subEntitys);
						//生成JSP文件
						generateJsp(rt, jwpPath, packageName, masterTe.getName());
						//生成导入导出模板文件
						generateExcelTemplate(rt, jwpPath, packageName, masterTe);
					}
					tes.setQuerySql(sqlList);
					return tes;
				} else {
					return null;
				}
			} else {
				return null;
			}
		} else {
			return null;
		}
	}
	
	/**
	 * 处理单个实体
	 * 
	 * @param ti
	 * @param entityName 实体名称
	 * @return
	 */
	private static TableEntity handleGsTable(Form ti, String entityName, List<QuerySql> sqlList) {
		TableEntity te = new TableEntity();
		te.setName(ti.getKey());
		te.setCaption(ti.getCaption());
		te.setEntityName(entityName);
		te.setListType(ti.getListType());//列表显示类型
		//表名大写
		te.setTableName(ti.getTableName());
		te.setIsSubEntity(!ti.getIsMaster());
		//公用表
		te.setIsCommon(ti.getIsCommon());
		//是否引用公用表
		te.setIsReferCommon(ti.getIsReferCommon());
		//加入库存相关属性
		te.setFormType(ti.getFormType());
		te.setStockType(ti.getStockType());
		te.setInOutVal(ti.getInOutVal());
		//加入导入、导出属性
		te.setEnableExport(ti.getEnableExport());
		te.setEnableImport(ti.getEnableImport());
		//将列表查询语句加入sql列表
		Sql querySql1 = null;
		if (null != ti.getExtension()
				&& null != ti.getExtension().getQueryPage()) {
			querySql1 = ti.getExtension().getQueryPage()
					.getQuerySql();
		}
		QuerySql qs1 = new QuerySql();
		String key1 = entityName + Constants.NAME_SPLIT_SYMBOL
				+ Constants.QUERY_LIST_SQL_KEY;
		qs1.setKey(key1);
		if (ti.getIsReferCommon()) {
			if (null != querySql1) {
				if (StringUtils.isBlank(querySql1.getContent())) {
					querySql1.setContent(ti.buildHql());
				}
			} else {
				querySql1 = new Sql();
				querySql1.setContent(ti.buildHql());
			}
		}
		if (null != querySql1) {
			qs1.setSql(querySql1);
			sqlList.add(qs1);
		}
		//公用表sql语句
		if(ti.getIsCommon()) {
			QuerySql qs = new QuerySql();
			String key = entityName + Constants.NAME_SPLIT_SYMBOL
					+ Constants.COMMON_QUERY_SQL_KEY;
			qs.setKey(key);
			Sql querySql = new Sql();
			querySql.setContent(ti.buildCommonHql());
			qs.setSql(querySql);
			sqlList.add(qs);
		}
		if(null!=ti.getFieldList()) {
			List<TeAttr> teAttr = new ArrayList<TeAttr>();
			for(Field fi : ti.getFieldList()) {
				if(StringUtils.isNotBlank(fi.getKey())){
					TeAttr ta = null;
					if(null==fi.getIsVirtual() || !fi.getIsVirtual()) {
						//非虚拟字段
						ta = new TeAttr();
						//属性名变大写
						DataProperties fs = fi.getDataProperties();
						ta.setColumnName(fs.getColName());
						ta.setIsNotNull(fs.getNotNull());
						ta.setIsUnique(fs.getUnique());
						//将字段名转成属性名，去除"_"
						ta.setName(fs.getKey());
						ta.setSize(fs.getSize());
						ta.setType(fs.getDataType());
						ta.setScale(fs.getScale());
						//字段所属实体，用于关联表
						String eName = fi.getEntityName();
						if(StringUtils.isNotBlank(eName)) {
							ta.setEntityName(eName);
							te.addReferEntityNameToList(eName);
						}
						//加入库存相关属性
						ta.setSyncEntityName(fi.getSyncEntityName());
						ta.setSyncKey(fi.getSyncKey());
						ta.setFromEntityName(fi.getFromEntityName());
						//加入导入、导出属性
						ta.setEnableExport(fi.getEnableExport());
						ta.setEnableImport(fi.getEnableImport());
						//导入重复校验字段
						ta.setCheckImportUnique(fi.getCheckImportUnique());
						//作为共享用户字段
						ta.setUseAsShareUser(fi.getQueryProperties().getUseAsShareUser());
						//作为权限控制字段
						ta.setUseAsAuthField(fi.getQueryProperties().getUseAsAuthField());
						ta.setAutoIdRule(fi.getEditProperties().getAutoIdRule());//自动编号规则
						ta.setDtFormat(fi.getEditProperties().getDtFormat());//数据显示格式
						
						//add by GaoXJ 2016-02-27
						ta.setShowInSearch(fi.getQueryProperties().getShowInSearch());
						ta.setSearchType(fi.getQueryProperties().getSearchType());
						ta.setShowInGrid(fi.getQueryProperties().getShowInGrid());
						ta.setSortable(fi.getQueryProperties().getSortable());
						ta.setFilterable(fi.getQueryProperties().getFilterable());
						ta.setEditType(fi.getEditProperties().getEditType());
						
						ta.setDefaultVal(fi.getEditProperties().getDefaultValue());//默认值
						ta.setExpRule(fi.getEditProperties().getExpCode());//公式代码
						ta.setColumnType(fi.getDataProperties().getDataType());//字段类型
						ta.setFieldIndex(String.valueOf(fi.getIndex()));//字段索引
						ta.setVisible(fi.getEditProperties().getVisible());//默认可见
						
						//添加系统字典sqlKey
						if(EditProperties.EDIT_TYPE_DICT_TREE.equalsIgnoreCase(fi.getEditProperties().getEditType())) {
							String key = EditProperties.EDIT_TYPE_DICT_TREE + Constants.NAME_SPLIT_SYMBOL + 
										entityName + Constants.NAME_SPLIT_SYMBOL + fi.getKey();
							String dtFormat = fi.getEditProperties().getDtFormat();
							if(StringUtils.isNotBlank(dtFormat)) {
								key = EditProperties.EDIT_TYPE_DICT_TREE + Constants.NAME_SPLIT_SYMBOL + Constants.SYS_TREE
										+ Constants.NAME_SPLIT_SYMBOL + dtFormat;
							}
							ta.setQueryDsSqlKey(key);
						}
						
						teAttr.add(ta);
					}
					EditProperties ep = fi.getEditProperties();
					if (null!=ep) {
						Formula fm = ep.getFormula();
						if(null!=fm) {
							if(Formula.TYPE_MODULE == fm.getType()) { //模块
								QuerySql qs = new QuerySql();
								String key = entityName + Constants.NAME_SPLIT_SYMBOL + fi.getKey() + Constants.NAME_SPLIT_SYMBOL + fm.getSql().getKey();
								qs.setKey(key);
								qs.setQuerySourceType(Formula.TYPE_MODULE);
								qs.setDataType(fi.getDataProperties().getDataType());
								qs.setSql(fm.getSql());
								sqlList.add(qs);
								if(null!=ta) {
									ta.setQueryDsSqlKey(key);
								}
							} else if(Formula.TYPE_ITEM == fm.getType()) { //固定值
								QuerySql qs = new QuerySql();
								String key = entityName + Constants.NAME_SPLIT_SYMBOL + fi.getKey() + Constants.NAME_SPLIT_SYMBOL + Constants.FIX_ITEM;
								qs.setKey(key);
								qs.setQuerySourceType(Formula.TYPE_ITEM);
								qs.setDataType(fi.getDataProperties().getDataType());
								qs.setItemList(fm.getItemList());
								sqlList.add(qs);
								if(null!=ta) {
									ta.setQueryDsSqlKey(key);
								}
							} else if(Formula.TYPE_SQL == fm.getType()) { //sql
								String key = entityName + Constants.NAME_SPLIT_SYMBOL + fi.getKey() + Constants.NAME_SPLIT_SYMBOL + fm.getRefKey();
								if(null!=ta && !ep.getAutoComplete()) { //非自动完成
									String refQsKey = fm.getRefQsKey();
									if(StringUtils.isNotBlank(refQsKey)) {//如果存在查询数据源，则使用查询数据源数据
										ta.setQueryDsSqlKey(refQsKey);
									} else {//编辑数据源
										ta.setQueryDsSqlKey(key);
									}
									ta.setQueryEditSqlKey(key);//编辑数据源，字段权限控制使用
								}
							}
						}
						List<Sql> sl = ep.getSqlList();
						if(null!=sl && !sl.isEmpty()) {
							for(Sql sql : sl) {
								QuerySql qs = new QuerySql();
								String key = entityName + Constants.NAME_SPLIT_SYMBOL + fi.getKey() + Constants.NAME_SPLIT_SYMBOL + sql.getKey();
								qs.setKey(key);
								qs.setDataType(fi.getDataProperties().getDataType());
								qs.setSql(sql);
								sqlList.add(qs);
							}
						}
						//DialogueWindow控件类型不需要翻译
						if(EditProperties.EDIT_TYPE_DIALOGUE_WINDOW.equalsIgnoreCase(ep.getEditType())) {
							ta.setQueryDsSqlKey(null);
						}
					}
				}
			}
			//加入系统自动添加字段
			addSystemField(ti, teAttr, sqlList, entityName);
			te.setTeAttr(teAttr);
		}
		if(null!=ti.getIsVirtual() && ti.getIsVirtual()) {
			te.setIsVirtual(true); // 虚拟实体设置
		} else {
			te.setIsVirtual(false);
		}
		return te;
	}
	
	/**
	 * 加入系统自动添加字段
	 * 
	 * @param ti
	 * @param teAttr
	 */
	private static void addSystemField(Form ti, List<TeAttr> teAttr, List<QuerySql> sqlList, String entityName) {
		//为了excel导出系统字段，添加sql查询用户姓名。
		QuerySql qs = new QuerySql();
		String key = /*entityName + Constants.NAME_SPLIT_SYMBOL +*/ Constants.CREATE_USER + Constants.NAME_SPLIT_SYMBOL + "sql1";
		qs.setKey(key);
		qs.setQuerySourceType(Formula.TYPE_SQL);
		qs.setDataType(DataProperties.DATA_TYPE_LONG);
		Sql sql = new Sql();
		sql.setKey("sql1");
		sql.setIsCheckAuth(false);
		sql.setDataStatus(Sql.STATUS_0);
		sql.setContent("select ID, NICKNAME,REAL_NAME FROM SYS_USER");
		List<Item> setValueItemList = new ArrayList<Item>();
		Item item = new Item();
		item.setKey("key");
		item.setColumn(Constants.ID);
		setValueItemList.add(item);
		item = new Item();
		item.setKey("caption");
		item.setColumn(Constants.NICK_NAME);
		setValueItemList.add(item);
		item = new Item();
		item.setKey("realName");
		item.setColumn(Constants.REAL_NAME);
		setValueItemList.add(item);
		sql.setSetValueItemList(setValueItemList);
		qs.setSql(sql);
		sqlList.add(qs);
		//固定值
		qs = new QuerySql();
		String key2 = entityName + Constants.NAME_SPLIT_SYMBOL + Constants.STATUS + Constants.NAME_SPLIT_SYMBOL + "fixItem";
		qs.setKey(key2);
		qs.setQuerySourceType(Formula.TYPE_ITEM);
		qs.setDataType(DataProperties.DATA_TYPE_STRING);
		List<Item> itemList = new ArrayList<Item>();
		//获取系统状态
		Map<String, String> statusMap = Constants.SYSTEM_STATUS_MAP;
		for(Map.Entry<String, String> en : statusMap.entrySet()) {
			item = new Item();
			item.setKey(en.getKey());
			item.setCaption(en.getValue());
			itemList.add(item);
		}
		qs.setItemList(itemList);
		sqlList.add(qs);
		for(TeAttr t : ti.getSystemFields()) {
			if(Constants.CREATE_USER.equals(t.getName()) || Constants.LAST_UPDATE_USER.equals(t.getName())) {
				t.setQueryDsSqlKey(key);
			}
			if(Constants.STATUS.equals(t.getName())) {
				t.setQueryDsSqlKey(key2);
			}
			t.setEnableExport(true);
			teAttr.add(t);
		}
	}
	
	
	/**
	 * 根据菜单文件生成weex应用的router.js和weexplus.json文件
	 * @param  menu
	 * @return
	 * 
	 */
	private static void generateMenuXml(Menu menu,String jwpPath,String  jsversion){
		String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
		FreeMarkerEngine free = new FreeMarkerEngine(concat(classPath, Constants.TEMPLATE_PATH));
		Map<String,Object> model=new HashMap<String, Object>();
		List<Business> businessList = menu.getBusiness();
		 List<com.qyxx.jwp.menu.Module> appModules = new ArrayList<>();
		for(Business business : businessList){
			List<Modules> modulesList = business.getModules();
			for(Modules modules : modulesList){
				List<com.qyxx.jwp.menu.Module> moduleList = modules.getModule();
				for(com.qyxx.jwp.menu.Module module : moduleList){
						generateModule(module,appModules);
				}
			}
		}
		model.put("appModules", appModules);
		String saveFilePath = jwpPath + Constants.GS_PACKAGE_APP_PATH+Constants.WEEX_ROUTER_FILE;
		try {
			free.create(Constants.WEEX_ROUTER_FTL_PATH, model, saveFilePath, ENCODE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new GscException("生成weex路由配置文件" + saveFilePath + "时出现异常", e);
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			throw new GscException("生成weex路由配置文件" + saveFilePath + "时出现异常", e);
		}

		Map<String,Object> map=new HashMap<String, Object>();
		int  jsvs = Integer.parseInt(jsversion);
        map.put("jsVersion",jsvs);
        String  sfp = jwpPath + Constants.GS_PACKAGE_APP_PATH+Constants.WEEX_WEEXPLUS_FILE;

		try {
			free.create(Constants.WEEX_WEEXPLUS_FTL_PATH, map, sfp, ENCODE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new GscException("生成weexplus.json配置文件" + sfp + "时出现异常", e);
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			throw new GscException("生成weexplus.json配置文件" + sfp + "时出现异常", e);
		}
	}
	
	/**
	 * 处理模块，如果是app模块或字典表，就放到appModules列表里
	 * @param module
	 * @param appModules
	 */
	private static void generateModule(com.qyxx.jwp.menu.Module module,List<com.qyxx.jwp.menu.Module> appModules) {
		if(com.qyxx.jwp.menu.Module.TYPE_MODULES.equalsIgnoreCase(module.getType())){
		List<com.qyxx.jwp.menu.Module> moduleList = module.getModule();	
		for(com.qyxx.jwp.menu.Module md : moduleList){		
				generateModule(md,appModules);
		}
		}else if(com.qyxx.jwp.menu.Module.TYPE_DICT.equalsIgnoreCase(module.getType())||com.qyxx.jwp.menu.Module.TYPE_APP.equalsIgnoreCase(module.getType())){
			    appModules.add(module);
		}
	}

	/**
	 * 根据实体配置生成Hibernate hbm xml配置文件
	 * 
	 * @param te
	 * @return
	 */
	private static String generateHbmXml(TableEntity te, String jwpPath) {
		String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
		FreeMarkerEngine free = new FreeMarkerEngine(concat(classPath, Constants.TEMPLATE_PATH));
		Map<String,TableEntity> map=new HashMap<String, TableEntity>();
		map.put("entity", te);
		String xmlPath = jwpPath + Constants.HBM_PATH + te.getEntityName() + Constants.XML_CONFIG_FILE_SUFFIX;
		try {
			free.create(Constants.HBM_FTL_PATH, map, xmlPath, ENCODE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			throw new GscException("生成hbm配置文件" + xmlPath + "时出现异常", e);
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			throw new GscException("生成hbm配置文件" + xmlPath + "时出现异常", e);
		}
		return xmlPath;
	}
	
	/**
	 * 生成JSP文件
	 * 生成vue文件
	 * 
	 * @param rt
	 */
	private static void generateJsp(Module rt, String jwpPath, String moduleName, String entityName) {
		String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
		FreeMarkerEngine free=new FreeMarkerEngine(concat(classPath, Constants.TEMPLATE_PATH));
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("root", rt);
		map.put("newWritableNumberArray", new NewWritableNumberArrayMethod());
		map.put("modifyArrayDirective", new ModifyArrayDirective());
		map.put("freeMarkerExcel", new FreeMarkerExcel());
		//String xmlPath = appPath + Constants.GS_JSP_PATH + moduleName + Constants.PATH_SEPARATOR + entityName.toLowerCase();
		//JSP文件路径
		String dirPath = jwpPath + Constants.GS_MODULES_JSP_PATH + moduleName + Constants.PATH_SEPARATOR;
		String xmlPath = dirPath + entityName.toLowerCase();
		//VUE文件 
		String destPath = jwpPath+ Constants.GS_PACKAGE_APP_PATH + Constants.GS_MODULES_VUE_PATH + moduleName + Constants.PATH_SEPARATOR;
		String vuePath = destPath + moduleName.toLowerCase();
		try {
			if(ModuleProperties.TYPE_DICT.equalsIgnoreCase(rt.getModuleProperties().getType())) {
				//业务字典模块
				free.create(Constants.JSP_DICT_LIST_FTL_PATH, map, xmlPath + "-list.jsp", ENCODE);
				free.create(Constants.VUE_DICT_LIST_FTL_PATH, map, vuePath + "-list.vue", ENCODE);
				free.create(Constants.VUE_DICT_VIEW_FTL_PATH, map, vuePath + "-view.vue", ENCODE);
				free.create(Constants.VUE_DICT_EDIT_FTL_PATH, map, vuePath + "-edit.vue", ENCODE);
				free.create(Constants.VUE_DICT_FILTER_FTL_PATH, map, vuePath + "-filter.vue", ENCODE);
			}else if(ModuleProperties.TYPE_FORM.equalsIgnoreCase(rt.getModuleProperties().getType())){
				xmlPath = jwpPath + Constants.GS_MODULES_JSP_PATH +Constants.MENU_MODULES_TYPE_FORMS + Constants.PATH_SEPARATOR+entityName.toLowerCase();
				free.create(Constants.JSP_FORM_JSP_FTL_PATH, map, xmlPath+ ".jsp" , ENCODE);
			}else if(ModuleProperties.TYPE_APP.equalsIgnoreCase(rt.getModuleProperties().getType())){//app页面
				free.create(Constants.VUE_APP_LIST_FTL_PATH, map, vuePath + "-list.vue", ENCODE);
				free.create(Constants.VUE_APP_VIEW_FTL_PATH, map, vuePath + "-view.vue", ENCODE);
				free.create(Constants.VUE_APP_EDIT_FTL_PATH, map, vuePath + "-edit.vue", ENCODE);
				free.create(Constants.VUE_APP_FILTER_PATH, map, vuePath + "-filter.vue", ENCODE);
			}else {			
				//普通模块
				//free.create(Constants.JSP_ADD_FTL_PATH, map, xmlPath + "-add.jsp", ENCODE);
				//free.create(Constants.JSP_EDIT_FTL_PATH, map, xmlPath + "-edit.jsp", ENCODE);
				free.create(Constants.JSP_VIEW_FTL_PATH, map, xmlPath + "-view.jsp", ENCODE);
				free.create(Constants.JSP_LIST_FTL_PATH, map, xmlPath + "-list.jsp", ENCODE);
				List<Form> formList = rt.getDataSource().getFormList();
				/*for(Form form : formList){
				 * 
					if(!form.getIsMaster()) {
						Map<String, Form> subMap = new HashMap<String, Form>();
						subMap.put("root", form);
						String subPath = dirPath + form.getKey().toLowerCase();
						free.create(Constants.JSP_SUB_FTL_PATH, subMap, subPath + "-sub.jsp", ENCODE);
					}
				}*/
				//复制到应用目录下
				//String destDirPath = appPath + Constants.GS_JSP_PATH + moduleName;
				//FileUtils.copyDirectory(new File(dirPath), new File(destDirPath));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			throw new GscException("生成" + xmlPath + "对应的jsp文件时时出现异常", e);
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			throw new GscException("生成" + xmlPath + "对应的jsp文件时时出现异常", e);
		}
	}
	
	/**
	 * 生成Excel导入导出模板及导入数据映射文件
	 * 
	 * @param rt
	 */
	private static void generateExcelTemplate(Module rt, String jwpPath, String moduleName, TableEntity te) {
		if(te.getEnableImport()) {
			String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
			String excelTemplatePath = concat(classPath, Constants.EXCEL_TEMPLATE_PATH);
			String dirPath = concat(jwpPath, Constants.EXCEL_PATH);
			try {
				FileUtils.forceMkdir(new File(dirPath)); //创建excel目录
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			//开启导入功能
			//1、生成导入Excel数据导入映射文件
			FreeMarkerEngine free=new FreeMarkerEngine(excelTemplatePath);
			Map<String,Object> map=new HashMap<String, Object>();
			map.put("root", rt);
			String xmlPath = concat(dirPath, moduleName, Constants.EXCEL_MAPPING_FILE_SUFFIX);
			try {
				free.create(Constants.EXCEL_MAPPING_FTL_NAME, map, xmlPath, ENCODE);
			} catch (IOException e) {
				throw new GscException("生成" + xmlPath + "对应的Excel导入映射文件时时出现异常", e);
			} catch (TemplateException e) {
				throw new GscException("生成" + xmlPath + "对应的Excel导入映射文件时出现异常", e);
			}
			
			//2、生成导入Excel模板文件和导入异常模板文件
			String templateFilePath = concat(excelTemplatePath, Constants.EXCEL_TEMPLATE_FILE_NAME);
			String destFilePath = concat(dirPath, moduleName, Constants.EXCEL_TEMPLATE_FILE_SUFFIX);
			List<String> sheetNameList = Lists.newArrayList();
			List<Form> sheetDataList = Lists.newArrayList();
			List<Form> formList = rt.getDataSource().getFormList();
			for(Form form : formList){
				if(form.getEnableImport()) {
					List<Field> importFieldList = Lists.newArrayList();
					List<Field> fieldList = form.getFieldList();
					if(null!=fieldList && !fieldList.isEmpty()) {
						for(Field fd : fieldList) {
							if(fd.getEnableImport()) {
								//字段开启导入
								if(DataProperties.DATA_TYPE_DATETIME.equalsIgnoreCase(fd.getDataProperties().getDataType())) {
									String tagInfo = JxlsUtils.getTagInfo(fd.getKey(), true);
									fd.setTagInfo(tagInfo);
								} else {
									String tagInfo = JxlsUtils.getTagInfo(fd.getKey());
									fd.setTagInfo(tagInfo);
								}
								importFieldList.add(fd);
							}
						}
					}
					if(form.getIsMaster()) {
						String tagInfo = JxlsUtils.getTagInfo(Constants.SYSTEM_CODE);
						form.setTagInfo(tagInfo);
					} else {
						String tagInfo = JxlsUtils.getTagInfo(Constants.REF_SYSTEM_CODE);
						form.setTagInfo(tagInfo);
					}
					String entityName = form.getEntityName();
					form.setForTagPrefixInfo(JxlsUtils.getForTagInfoPrefix(entityName));
					form.setForTagSuffixInfo(JxlsUtils.FOR_TAGINFO_SUFFIX);
					//sheetNameList.add(form.getCaption());
					//sheetDataList.add(form);
					Form importForm = new Form();
					/*try {
						BeanUtils.copyProperties(importForm, form);
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (Exception e) {
						e.printStackTrace();
					}*/
					importForm.setCaption(form.getCaption());
					importForm.setIsMaster(form.getIsMaster());
					importForm.setTagInfo(form.getTagInfo());
					importForm.setForTagPrefixInfo(form.getForTagPrefixInfo());
					importForm.setForTagSuffixInfo(form.getForTagSuffixInfo());
					
					importForm.setFieldList(importFieldList);
					sheetNameList.add(importForm.getCaption());
					sheetDataList.add(importForm);
				}
			}
			try {
				JxlsUtils.createImportExcelTemplate(templateFilePath, sheetNameList, sheetDataList, destFilePath);
			} catch (Exception e) {
				throw new GscException("生成" + destFilePath + "对应的Excel导入模板文件时时出现异常", e);
			} 
			//生成导入异常数据模板
			String expTemplateFilePath = concat(excelTemplatePath, Constants.EXCEL_EXP_TEMPLATE_FILE_NAME);
			String expDestFilePath = concat(dirPath, moduleName, Constants.EXCEL_EXP_TEMPLATE_FILE_SUFFIX);
			try {
				//加入导入异常原因字段
				for(Form form : sheetDataList) {
					Field field = new Field();
					field.setCaption(GsMngManager.IMPORT_MSG_CAPTION);
					field.setKey(GsMngManager.IMPORT_MSG);
					field.setEnableImport(true);
					field.setTagInfo(JxlsUtils.getTagInfo(field.getKey()));
					form.getFieldList().add(field);
				}
				JxlsUtils.createImportExcelTemplate(expTemplateFilePath, sheetNameList, sheetDataList, expDestFilePath);
			} catch (Exception e) {
				throw new GscException("生成" + expDestFilePath + "对应的Excel异常数据模板文件时时出现异常", e);
			} 
		}
		
		//3、生成导出Excel模板文件
		if(te.getEnableExport()) {
			String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
			String excelTemplatePath = concat(classPath, Constants.EXCEL_TEMPLATE_PATH);
			String dirPath = concat(jwpPath, Constants.EXCEL_PATH);
			try {
				FileUtils.forceMkdir(new File(dirPath)); //创建excel目录
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			String templateFilePath = concat(excelTemplatePath, Constants.EXCEL_EXPORT_TEMPLATE_FILE_NAME);
			String destFilePath = concat(dirPath, moduleName, Constants.EXCEL_EXPORT_TEMPLATE_FILE_SUFFIX);
			List<String> sheetNameList = Lists.newArrayList();
			List<Form> sheetDataList = Lists.newArrayList();
				
			List<Form> formList = rt.getDataSource().getFormList();
			for(Form form : formList){
				if(form.getEnableExport()) {
					List<Field> fieldList = form.getFieldList();
					if(null!=fieldList && !fieldList.isEmpty()) {
						for(Field fd : fieldList) {
							if(fd.getEnableExport()) {
								//字段开启导出
								if(DataProperties.DATA_TYPE_DATETIME.equalsIgnoreCase(fd.getDataProperties().getDataType())) {
									String tagInfo;
									//如果时间显示格式被设置了，就使用另一个方法初始化此单元格模版。
									if(!"".equals(fd.getEditProperties().getDtFormat())) {
										tagInfo = JxlsUtils.getTagInfo(fd.getKey(), form.getKey(), fd.getEditProperties().getDtFormat());
									} else {
										tagInfo = JxlsUtils.getTagInfo(fd.getKey(), true);
									}
									fd.setTagInfo(tagInfo);
								} else {
									String tagInfo = JxlsUtils.getTagInfo(fd.getKey());
									fd.setTagInfo(tagInfo);
								}
							}
						}
					}
					if(form.getIsMaster()) {
						String tagInfo = JxlsUtils.getTagInfo("id");
						form.setTagInfo(tagInfo);
					} else {
						if(form.getIsReferCommon()) {
							//引用关联表
							String tagInfo = JxlsUtils.getTagInfo("masterId");
							form.setTagInfo(tagInfo);
						} else {
							String refEntityName = EncodeUtils.toLowerOrUpperCaseFirstChar(te.getName(),true);
							String tagInfo = JxlsUtils.getTagInfo(concat(refEntityName, JxlsUtils.SPLIT_SYMBOL, "id"));
							form.setTagInfo(tagInfo);
						}
					}
					String entityName = form.getEntityName();
					form.setForTagPrefixInfo(JxlsUtils.getForTagInfoPrefix(entityName));
					form.setForTagSuffixInfo(JxlsUtils.FOR_TAGINFO_SUFFIX);
					//sheetNameList.add(form.getCaption());
					//sheetDataList.add(form);
					//克隆form，防止上下文引用此处理过的数据
					Form formclone = null;
					try {
						formclone = (Form)BeanUtils.cloneBean(form);
						ArrayList<Field> fieldListclone = new ArrayList<Field>();
						for(Field field : fieldList) {
							fieldListclone.add(field);
						}
						formclone.setFieldList(fieldListclone);
					} catch (Exception e) {
						e.printStackTrace();
					}
					List<ExportSystemField> exportSystemFieldList = formclone.getExportSystemFieldList();
					List<Field> fieldListclone = formclone.getFieldList();
					if(formclone.getIsMaster() && null!=exportSystemFieldList && !exportSystemFieldList.isEmpty()) {
						for(ExportSystemField exportSystemField : exportSystemFieldList) {
							if(exportSystemField.getEnableExport()) {
								//字段开启导出
								Field fd = new Field();
								if(exportSystemField.getName().equals("createTime") || exportSystemField.getName().equals("lastUpdateTime")) {
									String tagInfo = JxlsUtils.getTagInfo(exportSystemField.getName(), true);
									fd.setTagInfo(tagInfo);
								} else {
									String tagInfo = JxlsUtils.getTagInfo(exportSystemField.getName());
									fd.setTagInfo(tagInfo);
								}
								fd.setCaption(exportSystemField.getCaption());
								fd.setEnableExport(true);
								//这种做法改变了fieldList中正确的数据结构，可以通过修改excel生成模版更合理的实现将系统字段加入导出模版。
								fieldListclone.add(fd);
							}
						}
					}
					sheetNameList.add(formclone.getCaption());
					sheetDataList.add(formclone);
				}
			}
			try {
				JxlsUtils.createImportExcelTemplate(templateFilePath, sheetNameList, sheetDataList, destFilePath);
			} catch (Exception e) {
				throw new GscException("生成" + destFilePath + "对应的Excel导出模板文件时时出现异常", e);
			}
		}
	}
	
	/**
	 * 生成TableEntitys xml配置文件，供系统重启时自动加载使用
	 * 
	 * @param ts
	 */
	private static void generateTableEntitysXml(TableEntitys ts, String jwpPath) {
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance(TableEntitys.class);
			Marshaller marshaller = jaxbContext.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING, ENCODE);
			String dirPath = jwpPath + Constants.ENTITY_PATH;
			File file = new File(dirPath);
			if(!file.exists()) {file.mkdir();}
			marshaller.marshal(ts, new File(dirPath + ts.getName() + Constants.XML_CONFIG_FILE_SUFFIX));
		} catch (JAXBException e) {
			//e.printStackTrace();
			throw new GscException("生成" + ts.getName() + "对应的TableEntitys xml配置文件时出现异常", e);
		}
	}
	
	/**
	 * 将TableEntitys xml文件解析成对象
	 * 
	 * @param xmlPath
	 * @return
	 */
	private static TableEntitys parseTableEntitysXml(String xmlPath) {
		//JAXBContext context;
		try {
			JaxbBinder jb = new JaxbBinder(TableEntitys.class);
			String xml = FileUtils.readFileToString(new File(xmlPath), ENCODE);
			xml = EncryptAndDecryptUtils.aesDecrypt(xml, "");
			TableEntitys tes = jb.fromXml(xml);
			/*context = JAXBContext.newInstance(TableEntitys.class);
			FileReader fileReader = new FileReader(xmlPath);
			Unmarshaller um = context.createUnmarshaller();
			TableEntitys tes = (TableEntitys) um.unmarshal(fileReader);*/
			return tes;
		} catch (FileNotFoundException e) {
			//e.printStackTrace();
			throw new GscException("根据" + xmlPath + "生成java对象时出现异常，对应的xml文件不存在", e);
		} catch (IOException e) {
			throw new GscException("根据" + xmlPath + "生成java对象时出现异常", e);
		}
	}
	
	/**
	 * 解析GS包处理
	 * @param appPath 应用所在物理路径
	 */
	public static void handleGs(String appPath, File file, Boolean isFullUpdate) { 
		handleGs(appPath, isFullUpdate);
	}
	
	/**
	 * 生成业务字典JSP文件，将所有字典模块集中在一个页面显示
	 * 
	 * @param rt
	 */
	private static void generateDictsJsp(List<Modules> mdsList, String jwpPath) {
		String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
		FreeMarkerEngine free=new FreeMarkerEngine(concat(classPath, Constants.TEMPLATE_PATH));
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("mdsList", mdsList);
		//String xmlPath = appPath + Constants.GS_JSP_PATH + moduleName + Constants.PATH_SEPARATOR + entityName.toLowerCase();
		String dirPath = concat(jwpPath, Constants.GS_DICTS_JSP_PATH);
		String xmlPath = concat(dirPath, Constants.MENU_MODULES_TYPE_DICTS, Constants.JSP_SUFFIX);
		try {
			free.create(Constants.JSP_DICTS_JSP_FTL_PATH, map, xmlPath, ENCODE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			throw new GscException("生成" + xmlPath + "对应的jsp文件时时出现异常", e);
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			throw new GscException("生成" + xmlPath + "对应的jsp文件时时出现异常", e);
		}
	}
	/**
	 * 对每个模块设置EntityName
	 * @param md
	 * @param mds
	 * @param gp
	 */
	public static void getEveryModule(com.qyxx.jwp.menu.Module md,Modules mds,GsPackage gp){
		if(com.qyxx.jwp.menu.Module.TYPE_MODULES.equals(md.getType())){
			if(null!=md.getModule()&&!md.getModule().isEmpty()){
				for(com.qyxx.jwp.menu.Module md1 : md.getModule()) {
					getEveryModule(md1, mds, gp);
				}
			}	
		}else{
			String entityName = gp.getModuleEntityName(mds.getKey(), md.getKey());
			md.setEntityName(entityName);
		}
	}
	/**
	 * 生成菜单权限资源(包括weex的路由文件)
	 * 
	 * @param jwpPath
	 */
	public static String generateMenu(String jwpPath, GsPackage gp, Boolean isFullUpdate, List<String> updatedModules,String jsversion) {
		String jwpName = "";
		JaxbBinder jb = new JaxbBinder(Menu.class);
		String menuFileName = jwpPath + Constants.CONFIG_PATH + Constants.MENU_CONFIG_FILE_NAME;
		File file = new File(menuFileName);
		if(!file.exists()) {
			throw new GscException("系统菜单配置文件：" + menuFileName + "不存在，请检查上传文件");
		}
		try {
			String xml = FileUtils.readFileToString(file, ENCODE);
			xml = EncryptAndDecryptUtils.aesDecrypt(xml, "");
			Menu menu = jb.fromXml(xml);
			jwpName = menu.getName();
			List<Business> bsList = menu.getBusiness();
			//List<Modules> bsDictsList = new ArrayList<Modules>();
			//设置entityName值
			if(null!=bsList && !bsList.isEmpty()) {
				for(Business bs : bsList) {
					if(Constants.MENU_MODULE.equalsIgnoreCase(bs.getKey())||Constants.MENU_APP.equalsIgnoreCase(bs.getKey())) {
						//业务模块
						List<Modules> mdsList = bs.getModules();
						if(null!=mdsList && !mdsList.isEmpty()) {
							for(Modules mds : mdsList) {
								List<com.qyxx.jwp.menu.Module> mdList = mds.getModule();
								if(null!=mdList && !mdList.isEmpty()) {
									for(com.qyxx.jwp.menu.Module md : mdList) {
										getEveryModule(md, mds, gp);
									}
								}
								/*if(Constants.MENU_MODULES_TYPE_DICTS.equalsIgnoreCase(mds.getType())) {
									//业务字典
									bsDictsList.add(mds);
								}*/
							}
						}
					}
				}
			}
			//生成业务字典页面
			//generateDictsJsp(bsDictsList, jwpPath);
			//获取字段权限校验表单
			Map<String, List<Form>> fieldFormMap = getFieldAuthForms(gp);
			//生成菜单
			am.handleMenuResource(menu, fieldFormMap, getFormAuthButtons(gp), isFullUpdate, updatedModules);
			//生成weex路由文件
			generateMenuXml(menu,jwpPath,jsversion);
			return jwpName;
		} catch (IOException e) {
			throw new GscException("读取系统菜单配置文件：" + menuFileName + "出现异常", e);
		} 
	}
	
	/**
	 * 获取开启字段权限校验的表单
	 * 
	 * @param gp
	 * @return
	 */
	public static Map<String, List<Form>> getFieldAuthForms(GsPackage gp) {
		Map<String, List<Form>> map = Maps.newHashMap();
		Map<String, GsModule> mm = gp.getModuleMap();
		if(null!=mm) {
			for(GsModule gm : mm.values()) {
				if(null!=gm) {
					Map<String, Module> gmm = gm.getModuleMap();
					if(null!=gmm) {
						for(Map.Entry<String, Module> gmmr : gmm.entrySet()) {
							Module rt = gmmr.getValue();
							if(null!=rt) {
								DataSource gds = rt.getDataSource();
								if(null!=gds) {
									List<Form> tiList = gds.getFormList();
									if(null!=tiList && !tiList.isEmpty()) {
										List<Form> formList = Lists.newArrayList();
										for(Form f : tiList) { 
											if(f.getEnableFieldAuthCheck()) {
												formList.add(f);
											}
										}
										if(!formList.isEmpty()) {
											map.put(rt.getModuleProperties().getKey().toLowerCase(), formList);
										}
									}
								}
							}
						}
					}
				}
			}
		}
		return map;
	}
	
	/**
	 * 获取开启权限校验的表单自定义按钮
	 * 
	 * @param gp
	 * @return
	 */
	public static Map<String, List<Button>> getFormAuthButtons(GsPackage gp) {
		Map<String, List<Button>> map = Maps.newHashMap();
		Map<String, GsModule> mm = gp.getModuleMap();
		if(null!=mm) {
			for(GsModule gm : mm.values()) {
				if(null!=gm) {
					Map<String, Module> gmm = gm.getModuleMap();
					if(null!=gmm) {
						for(Map.Entry<String, Module> gmmr : gmm.entrySet()) {
							Module rt = gmmr.getValue();
							if(null!=rt) {
								DataSource gds = rt.getDataSource();
								if(null!=gds) {
									List<Form> tiList = gds.getFormList();
									if(null!=tiList && !tiList.isEmpty()) {
										List<Button> btList = Lists.newArrayList();
										for(Form f : tiList) { 
											if(null!=f.getExtension()) {
												if(null!=f.getExtension().getQueryPage()) {
													List<Button> buttList = f.getExtension().getQueryPage().getButtonList();
													if(null!=buttList && !buttList.isEmpty()) {
														for(Button bt : buttList) {
															if(bt.getEnableAuthCheck()) { //校验权限
																bt.setFormCaption(f.getCaption());
																bt.setFormKey(f.getKey());
																bt.setFormEntityName(f.getEntityName());
																bt.setInWhichPage(Button.IN_QUERY_PAGE);
																btList.add(bt);
															}
															List<Button> subBtList = bt.getButtonList();//子按钮
															if(null!=subBtList && !subBtList.isEmpty()) {
																for(Button subBt : subBtList) {
																	if(subBt.getEnableAuthCheck()) {
																		subBt.setFormCaption(f.getCaption());
																		subBt.setFormKey(f.getKey());
																		subBt.setFormEntityName(f.getEntityName());
																		subBt.setInWhichPage(Button.IN_QUERY_PAGE);
																		btList.add(subBt);
																	}
																}
															}
														}
													}
												}
												if(null!=f.getExtension().getEditPage()) {
													List<Button> buttList = f.getExtension().getEditPage().getButtonList();
													if(null!=buttList && !buttList.isEmpty()) {
														for(Button bt : buttList) {
															if(bt.getEnableAuthCheck()) { //校验权限
																bt.setFormCaption(f.getCaption());
																bt.setFormKey(f.getKey());
																bt.setFormEntityName(f.getEntityName());
																bt.setInWhichPage(Button.IN_VIEW_PAGE);
																btList.add(bt);
															}
															List<Button> subBtList = bt.getButtonList();//子按钮
															if(null!=subBtList && !subBtList.isEmpty()) {
																for(Button subBt : subBtList) {
																	if(subBt.getEnableAuthCheck()) {
																		subBt.setFormCaption(f.getCaption());
																		subBt.setFormKey(f.getKey());
																		subBt.setFormEntityName(f.getEntityName());
																		subBt.setInWhichPage(Button.IN_VIEW_PAGE);
																		btList.add(subBt);
																	}
																}
															}
														}
													}
												}
											}
										}
										if(!btList.isEmpty()) {
											map.put(rt.getModuleProperties().getKey().toLowerCase(), btList);
										}
									}
								}
							}
						}
					}
				}
			}
		}
		return map;
	}
	
	/**
	 * 复制jsp文件
	 */
	public static void doCopyJspFileToAppDir(String defaultDir, Boolean isFullUpdate) {
		String srcDir = concat(defaultDir, Constants.GS_PACKAGE_JSP_PATH);
		String destDir = appRootPath + Constants.GS_JSP_PATH;
		try {
			File srcFile = new File(srcDir);
			if(!srcFile.exists()) {
				srcFile.mkdir();
			}
			File destFile = new File(destDir);
			if(!destFile.exists()) {
				destFile.mkdir();
			} else {
				if(isFullUpdate) {
					//先删除原有文件夹
					File gsFile = new File(concat(destDir, Constants.GS_PATH));
					if(gsFile.exists()) {
						FileUtils.forceDelete(gsFile);
					}
				}
			}
			FileUtils.copyDirectory(srcFile, destFile);
		} catch (IOException e) {
			throw new GscException("复制jsp文件出现异常", e);
		}
	}
	
	
	/**
	 * 复制vue文件
	 */
	public static void doCopyVueFileToMobileDir(String defaultDir,String itemName,Boolean isFullUpdate) {
		String srcDir = concat(defaultDir,Constants.GS_PACKAGE_APP_PATH, Constants.GS_PACKAGE_VUE_PATH);
		String destDir = sp.getQxAppPath() +Constants.WEEX_BOOKS_PATH+itemName+ Constants.PATH_SEPARATOR+ Constants.GS_PACKAGE_VUE_PATH;
		try {
			File srcFile = new File(srcDir);
			if(!srcFile.exists()) {
				srcFile.mkdir();
			}
			File destFile = new File(destDir);
			if(!destFile.exists()) {
				destFile.mkdir();
			} else {
				if(isFullUpdate) {
					//先删除原有文件夹
					File gsFile = new File(concat(destDir, Constants.GS_PATH));
					if(gsFile.exists()) {
						FileUtils.forceDelete(gsFile);
					}
				}
			}
			FileUtils.copyDirectory(srcFile, destFile);
		} catch (IOException e) {
			throw new GscException("复制vue文件出现异常", e);
		}
	}
	
	/**
	 * 复制router.js配置文件
	 */
	public static void  doCopyRouterFileToAppDir(String defaultDir,String itemName){
		String src = concat(defaultDir,Constants.GS_PACKAGE_APP_PATH,Constants.WEEX_ROUTER_FILE);
		String dest = sp.getQxAppPath()+Constants.WEEX_BOOKS_PATH+itemName+ Constants.PATH_SEPARATOR ;
		File srcFile = new File(src);
		File destDir = new File(dest);
		if(srcFile.exists()){
			try {
				FileUtils.copyFileToDirectory(srcFile, destDir);;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new GscException("复制router.js文件出现异常",e);
			}
		}
	}

	/**
	 * 复制weexplus.json配置文件
	 */
	public static void  doCopyWeexplusFileToAppDir(String defaultDir){
		String src = concat(defaultDir,Constants.GS_PACKAGE_APP_PATH,Constants.WEEX_WEEXPLUS_FILE);
		String dest = sp.getQxAppPath()+Constants.WEEX_WEEXPLUS_PATH ;
		File srcFile = new File(src);
		File destDir = new File(dest);
		if(srcFile.exists()){
			try {
				FileUtils.copyFileToDirectory(srcFile, destDir);;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new GscException("复制weexplus.json文件出现异常",e);
			}
		}
	}
	
	
	
	/**
	 * 复制config文件
	 * 
	 * @param filePath
	 * @param packagePath
	 */
	public static void doCopyFileToDefaultConfigDir(String jwpPath, String defaultJwpPath, Boolean isFullUpdate) {
		String srcDir = jwpPath;
		String destDir = defaultJwpPath;
		try {
			File destDirFile = new File(destDir);
			if(isFullUpdate && destDirFile.exists()) {
				//先删除原有文件夹
				FileUtils.forceDelete(destDirFile);
			} 
			FileUtils.forceMkdir(destDirFile);
			FileUtils.copyDirectory(new File(srcDir), destDirFile);
		} catch (IOException e) {
			throw new GscException("复制config文件出现异常", e);
		}
	}
	
	/**
	 * 复制i18n资源文件，全量更新
	 */
	public static void doCopyI18nFileToAppDir(String defaultDir, Boolean isFullUpdate) {
		String srcDir = concat(defaultDir, Constants.I18N_PATH, Constants.MODULE_PATH);
		String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
		String destDir = concat(classPath, Constants.I18N_PATH, Constants.MODULE_PATH);
		try {
			File srcFile = new File(srcDir);
			if(!srcFile.exists()) {
				FileUtils.forceMkdir(srcFile);
			}
			File destFile = new File(destDir);
			if(isFullUpdate && destFile.exists()) {
				//先删除原有文件夹
				FileUtils.forceDelete(destFile);
			}
			FileUtils.forceMkdir(destFile);
			FileUtils.copyDirectory(srcFile, destFile);
			String[] names = destFile.list(new DefaultFilenameFilter("properties"));
			//热加载资源文件
			doUpdateI18nCache(names);
		} catch (IOException e) {
			throw new GscException("复制jsp文件出现异常", e);
		}
	}
	
	/**
	 * 复制移动端i18n资源文件，全量更新
	 */
	public static void doCopyI18nFileToMobileDir(String defaultDir,String  itemName, Boolean isFullUpdate) {
		String srcDir = concat(defaultDir,Constants.GS_PACKAGE_APP_PATH, Constants.I18N_PATH, Constants.MODULE_PATH);
		//String classPath = GsParseUtils.class.getResource(Constants.PATH_SEPARATOR).getPath();
		String destDir = concat(sp.getQxAppPath(),Constants.WEEX_BOOKS_PATH,itemName,Constants.PATH_SEPARATOR, Constants.I18N_PATH, Constants.MODULE_PATH);
		try {
			File srcFile = new File(srcDir);
			if(!srcFile.exists()) {
				FileUtils.forceMkdir(srcFile);
			}
			File destFile = new File(destDir);
			if(isFullUpdate && destFile.exists()) {
				//先删除原有文件夹
				FileUtils.forceDelete(destFile);
			}
			FileUtils.forceMkdir(destFile);
			FileUtils.copyDirectory(srcFile, destFile);
			String[] names = destFile.list(new DefaultFilenameFilter("properties"));
			//热加载资源文件
			//doUpdateI18nCache(names);
		} catch (IOException e) {
			throw new GscException("复制移动端i18n资源文件出现异常", e);
		}
	}
	
	
	
	/**
	 * 热加载资源文件
	 * 
	 * @param names
	 */
	public static void doUpdateI18nCache(String[] names) {
		if(null!=names && names.length > 0) {
			
			//重载资源文件
			LocalizedTextUtil.reset();
			try {
				clearMap(ResourceBundle.class, null, "cacheList");
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
            // now, for the true and utter hack, if we're running in tomcat, clear
            // it's class loader resource cache as well.
            clearTomcatCache();
            //重新载入system资源
            LocalizedTextUtil.addDefaultResourceBundle(Constants.SYSTEM_I18N);
			
			for(String name : names) {
				int index = name.lastIndexOf(Constants.NAME_SPLIT_SYMBOL);
				if(index >= 0) {
					String str = name.substring(0, index);
					String bundleName = concat(Constants.MODULE_I18N_PREFIX, str);
					//清除bundle缓存
					//LocalizedTextUtil.clearBundle(bundleName);
					
					String resourceBundleName = bundleName;
					int ind = str.indexOf(Constants.UNDERLINE);
					if(ind >= 0) {
						String s = str.substring(0, ind);
						resourceBundleName = concat(Constants.MODULE_I18N_PREFIX, s);
					}
					//添加支持资源名称
					LocalizedTextUtil.addDefaultResourceBundle(resourceBundleName);
				}
			}
		}
	}
	
	/**
	 * 加载hbm及entity
	 */
	private static void loadHbmEntity(String defaultDir) {
		//先加载hbm文件
		String hbmDir = concat(defaultDir, Constants.HBM_PATH);
		String[] filePaths = PathUtils.getDirFilePathList(hbmDir, "xml");
		if(null!=filePaths && filePaths.length > 0) {
			List<String> hbmXmlPathList = Lists.newArrayList();
			for(String filePath : filePaths) {
				hbmXmlPathList.add(hbmDir + filePath);
			}
			HibernateUtils.updateHibernateCfg(hbmXmlPathList, false);
		}
		//再加载TableEntity缓存文件
		String teDir = concat(defaultDir, Constants.ENTITY_PATH);
		filePaths = PathUtils.getDirFilePathList(teDir, "xml");
		if(null!=filePaths && filePaths.length > 0) {
			for(String filePath : filePaths) {
				TableEntitys tes = parseTableEntitysXml(teDir + filePath);
				if(null!=tes) {
					if(null!=tes.getTableEntity() && !tes.getTableEntity().isEmpty()) {
						for(TableEntity te : tes.getTableEntity()) {
							TableEntityCache.getInstance().put(te.getEntityName(), te);
						}
					}
					if(null!=tes.getQuerySql() && !tes.getQuerySql().isEmpty()) {
						for(QuerySql qs : tes.getQuerySql()) {
							SqlCache.getInstance().put(qs.getKey(), qs, tes.getModuleType());
						}
					}
					TableEntityCache.getInstance().putModuleName(tes.getName(), tes.getDisplayName());
				}
			}
		}
	}
	
	/**
	 * 应用启动时，自动加载缓存文件及Hbm文件
	 */
	public static void loadCacheOnStartup() {
		//复制所有i18n资源文件至应用目录
		try {
			String defaultDir = concat(sp.getUploadFilePath(), Constants.GS_PACKAGE_PATH, Constants.DEFAULT_CONFIG_FILE);
			loadHbmEntity(defaultDir);
			doCopyI18nFileToAppDir(defaultDir, false);
		} catch (Exception e) {
			e.printStackTrace();
		}
		/*//复制所有jsp文件至应用目录
		try {
			doCopyJspFileToAppDir(defaultDir);
		} catch (Exception e) {
			e.printStackTrace();
		}*/
	}
	
	/**
	 * 部署流程文件
	 * 
	 * @param configPath
	 */
	public static void deployFlow(String configPath, Boolean isFullUpdate, List<String> updatedModules) {
		String  flowFileDir = configPath + Constants.CONFIG_PATH + Constants.WORKFLOW_PATH;
		File dir = new File(flowFileDir);
		File[] files = dir.listFiles(new DefaultFilenameFilter(Constants.FLOW_FILE_SUFFIX));
		if(null!=files && files.length > 0) {
			if(!isFullUpdate) {
				List<File> list = Lists.newArrayList();
				for(File file : files) {
					String fileName = StringUtils.split(file.getName(),".")[0];
					if(updatedModules.contains(fileName)) {
						list.add(file);
					}
				}
				files = list.toArray(new File[]{});
			}
			ptm.deployFlow(files);
		}
	}
	
	/**
	 * 处理模块属性，生成i18n资源文件
	 * 
	 * 一个模块生成一个i18n资源文件，以模块key命名
	 * 
	 * @param module
	 */
	public static void generateI18nProperties(Module module, String jwpPath) {
		Map<String, StringBuilder> sbMap = new HashMap<String, StringBuilder>();
		//将语言配置修改为从数据库获取
		Set<DefinitionEntity> deSet = DefinitionCache.getSet("SYS_LOCALE_DICT", Constants.LOCALE[0]);
		for(DefinitionEntity de : deSet) {
			sbMap.put(de.getValue(), new StringBuilder(""));
		}
		/*
		sbMap.put(Constants.LOCALE[0], new StringBuilder(""));
		sbMap.put(Constants.LOCALE[1], new StringBuilder(""));
		sbMap.put(Constants.LOCALE[2], new StringBuilder(""));
		*/
		//处理模块
		String moduleKey = concat(Constants.MENU_MODULE, Constants.NAME_SPLIT_SYMBOL, module.getModuleProperties().getKey());
		String i18nKey = concat(moduleKey, Constants.TITLE);
		module.getModuleProperties().setI18nKey(i18nKey);
		appendI18nText(sbMap, module.getModuleProperties().getLanguageText(), i18nKey, module.getModuleProperties().getCaption());
		
		//处理表单
		DataSource ds = module.getDataSource();
		List<Form> formList = ds.getFormList();
		if(null!=formList && !formList.isEmpty()) {
			for(Form form : formList) {
				String formKey = concat(moduleKey, Constants.NAME_SPLIT_SYMBOL, Constants.FORM, Constants.NAME_SPLIT_SYMBOL, form.getKey());
				i18nKey = concat(formKey, Constants.TITLE);
				form.setI18nKey(i18nKey);
				appendI18nText(sbMap, form.getLanguageText(), i18nKey, form.getCaption());
				
				//处理字段
				List<Field> fieldList = form.getFieldList();
				if(null!=fieldList && !fieldList.isEmpty()) {
					for(Field field : fieldList) {
						String fieldKey = concat(formKey, Constants.NAME_SPLIT_SYMBOL, Constants.FIELD, Constants.NAME_SPLIT_SYMBOL, field.getKey());
						i18nKey = concat(fieldKey, Constants.TITLE);
						field.setI18nKey(i18nKey);
						appendI18nText(sbMap, field.getLanguageText(), i18nKey, field.getCaption());
					}
				}
				
				//处理扩展属性
				Extension et = form.getExtension();
				if(null!=et) {
					//处理查询按钮
					QueryPage qp = et.getQueryPage();
					if(null!=qp) {
						List<Button> btList = qp.getButtonList();
						if(null!=btList && !btList.isEmpty()) {
							for(Button bt : btList) {
								i18nKey = concat(formKey, Constants.NAME_SPLIT_SYMBOL, Constants.QUERY_BUTTON, Constants.NAME_SPLIT_SYMBOL, bt.getKey(), Constants.TITLE);
								bt.setI18nKey(i18nKey);
								appendI18nText(sbMap, bt.getLanguageText(), i18nKey, bt.getCaption());
							}
						}
					}
					//处理编辑按钮
					EditPage ep = et.getEditPage();
					if(null!=ep) {
						List<Button> btList = ep.getButtonList();
						if(null!=btList && !btList.isEmpty()) {
							for(Button bt : btList) {
								i18nKey = concat(formKey, Constants.NAME_SPLIT_SYMBOL, Constants.EDIT_BUTTON, Constants.NAME_SPLIT_SYMBOL, bt.getKey(), Constants.TITLE);
								bt.setI18nKey(i18nKey);
								appendI18nText(sbMap, bt.getLanguageText(), i18nKey, bt.getCaption());
							}
						}
					}
				}
			}
		}
		
		
		
		
		//处理Tab
		List<Tabs> tabsList = ds.getTabsList();
		if(null!=tabsList && !tabsList.isEmpty()) {
			for(Tabs tabs : tabsList) {
				List<Tab> tabList = tabs.getTabList();
				if(null!=tabList && !tabList.isEmpty()) {
					for(Tab tab : tabList) {
						i18nKey = concat(moduleKey, Constants.NAME_SPLIT_SYMBOL, Constants.TAB, tab.getRows(), 
								tab.getCols(), Constants.NAME_SPLIT_SYMBOL, tab.getForm(), Constants.TITLE);
						tab.setI18nKey(i18nKey);
						appendI18nText(sbMap, tab.getLanguageText(), i18nKey, tab.getCaption());
					}
				}
			}
		}
		
		//生成资源文件
		generateI18nFile(module.getModuleProperties().getKey(), sbMap, jwpPath);
	}
	
	
	/**
	 * 处理模块属性，生成i18n资源文件
	 * 
	 * 一个模块生成一个i18n资源文件，以模块key命名
	 * 
	 * @param module
	 */
	public static void generateI18nJS(Module module, String jwpPath) {
		Map<String,Map<String, String> > mm = new HashMap<String, Map<String, String>>();
		//将语言配置修改为从数据库获取
		Set<DefinitionEntity> deSet = DefinitionCache.getSet("SYS_LOCALE_DICT", Constants.LOCALE[0]);
		for(DefinitionEntity de : deSet) {
			mm.put(de.getValue(), new HashMap<String,String>());
		}
		/*
		sbMap.put(Constants.LOCALE[0], new StringBuilder(""));
		sbMap.put(Constants.LOCALE[1], new StringBuilder(""));
		sbMap.put(Constants.LOCALE[2], new StringBuilder(""));
		*/
		//处理模块
		String moduleKey = concat(Constants.MENU_MODULE, Constants.NAME_SPLIT_SYMBOL, module.getModuleProperties().getKey());
		String i18nKey = concat(moduleKey, Constants.TITLE);
		module.getModuleProperties().setI18nKey(i18nKey);
		appendI18nMap(mm, module.getModuleProperties().getLanguageText(), i18nKey, module.getModuleProperties().getCaption());
		
		//处理表单
		DataSource ds = module.getDataSource();
		List<Form> formList = ds.getFormList();
		if(null!=formList && !formList.isEmpty()) {
			for(Form form : formList) {
				String formKey = concat(moduleKey, Constants.NAME_SPLIT_SYMBOL, Constants.FORM, Constants.NAME_SPLIT_SYMBOL, form.getKey());
				i18nKey = concat(formKey, Constants.TITLE);
				form.setI18nKey(i18nKey);
				appendI18nMap(mm, form.getLanguageText(), i18nKey, form.getCaption());
				
				//处理字段
				List<Field> fieldList = form.getFieldList();
				if(null!=fieldList && !fieldList.isEmpty()) {
					for(Field field : fieldList) {
						String fieldKey = concat(formKey, Constants.NAME_SPLIT_SYMBOL, Constants.FIELD, Constants.NAME_SPLIT_SYMBOL, field.getKey());
						i18nKey = concat(fieldKey, Constants.TITLE);
						field.setI18nKey(i18nKey);
						appendI18nMap(mm, field.getLanguageText(), i18nKey, field.getCaption());
					}
				}
				
				//处理扩展属性
				Extension et = form.getExtension();
				if(null!=et) {
					//处理查询按钮
					QueryPage qp = et.getQueryPage();
					if(null!=qp) {
						List<Button> btList = qp.getButtonList();
						if(null!=btList && !btList.isEmpty()) {
							for(Button bt : btList) {
								i18nKey = concat(formKey, Constants.NAME_SPLIT_SYMBOL, Constants.QUERY_BUTTON, Constants.NAME_SPLIT_SYMBOL, bt.getKey(), Constants.TITLE);
								bt.setI18nKey(i18nKey);
								appendI18nMap(mm, bt.getLanguageText(), i18nKey, bt.getCaption());
							}
						}
					}
					//处理编辑按钮
					EditPage ep = et.getEditPage();
					if(null!=ep) {
						List<Button> btList = ep.getButtonList();
						if(null!=btList && !btList.isEmpty()) {
							for(Button bt : btList) {
								i18nKey = concat(formKey, Constants.NAME_SPLIT_SYMBOL, Constants.EDIT_BUTTON, Constants.NAME_SPLIT_SYMBOL, bt.getKey(), Constants.TITLE);
								bt.setI18nKey(i18nKey);
								appendI18nMap(mm, bt.getLanguageText(), i18nKey, bt.getCaption());
							}
						}
					}
				}
			}
		}
		
		
		
		
		//处理Tab
		List<Tabs> tabsList = ds.getTabsList();
		if(null!=tabsList && !tabsList.isEmpty()) {
			for(Tabs tabs : tabsList) {
				List<Tab> tabList = tabs.getTabList();
				if(null!=tabList && !tabList.isEmpty()) {
					for(Tab tab : tabList) {
						i18nKey = concat(moduleKey, Constants.NAME_SPLIT_SYMBOL, Constants.TAB, tab.getRows(), 
								tab.getCols(), Constants.NAME_SPLIT_SYMBOL, tab.getForm(), Constants.TITLE);
						tab.setI18nKey(i18nKey);
						appendI18nMap(mm, tab.getLanguageText(), i18nKey, tab.getCaption());
					}
				}
			}
		}
		
		
		//生成资源文件
		generateI18nJS(module.getModuleProperties().getKey(), mm, jwpPath);
	}
	
	
	/**
	 * 生成资源文件
	 * 
	 * @param fileName
	 * @param sbMap
	 */
	public static void generateI18nFile(String fileName, Map<String, StringBuilder> sbMap, String jwpPath) {
		String filePath = concat(jwpPath, Constants.I18N_PATH, Constants.MODULE_PATH, fileName);
		for(Map.Entry<String, StringBuilder> en : sbMap.entrySet()) {
			StringBuilder sb = en.getValue();
			String s = sb.toString();
			if(StringUtils.isNotBlank(s)) {
				String enKey = en.getKey();
				String fl = concat(filePath, Constants.UNDERLINE, enKey, Constants.I18N_SUFFIX);
				try {
					FileUtils.writeStringToFile(new File(fl), s, ENCODE);
					if(Constants.LOCALE[0].equals(enKey)) {
						//生成默认资源文件
						String dest = concat(filePath, Constants.I18N_SUFFIX);
						FileUtils.copyFile(new File(fl), new File(dest));
					}
				} catch (IOException e) {
					throw new GscException("生成资源文件" + fl + "出现异常", e);
				}
			}
		}
	}
	
	/**
	 * 生成资源文件app版
	 * 
	 * @param fileName
	 * @param sbMap
	 */
	public static void generateI18nJS(String fileName, Map<String, Map<String,String>> mm, String jwpPath) {
		String filePath = concat(jwpPath,Constants.GS_PACKAGE_APP_PATH, Constants.I18N_PATH, Constants.MODULE_PATH, fileName);
		for(Map.Entry<String, Map<String, String>> en : mm.entrySet()) {
			Map<String, String> sMap = en.getValue();
			if(!sMap.isEmpty()) {
				String s = jsonBinder.toJson(sMap);
				s = Constants.JSON_STRING_PREFIX+s;
				String enKey = en.getKey();
				String fl = concat(filePath, Constants.UNDERLINE, enKey, Constants.I18N_APP_SUFFIX);
				try {
					FileUtils.writeStringToFile(new File(fl), s, ENCODE);
					if(Constants.LOCALE[0].equals(enKey)) {
						//生成默认资源文件
						String dest = concat(filePath, Constants.I18N_APP_SUFFIX);
						FileUtils.copyFile(new File(fl), new File(dest));
					}
				} catch (IOException e) {
					throw new GscException("生成资源文件" + fl + "出现异常", e);
				}
			}
		}
	}
	
	/**
	 * 连接字符串
	 * 
	 * @param str
	 * @return
	 */
	public static String concat(Object... str) {
		StringBuilder sb = new StringBuilder("");
		if(null!=str && str.length > 0) {
			for(Object s : str) {
				sb.append(s);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 添加国际化资源
	 * 
	 * @param sbMap
	 * @param lgText
	 * @param i18nKey
	 * @param defaultCaption 中文名称
	 */
	public static void appendI18nText(Map<String, StringBuilder> sbMap, String lgText, String i18nKey, String defaultCaption) {
		if(StringUtils.isNotBlank(lgText)) {
			Map<String, String> map = jsonBinder.fromJson(lgText, HashMap.class);
			for(Map.Entry<String, String> entry : map.entrySet()) {
				String enKey = entry.getKey();
				String enVal = entry.getValue();
				if(StringUtils.isNotBlank(enKey) && StringUtils.isNotBlank(enVal)) {
					StringBuilder sb = sbMap.get(enKey);
					if(null!=sb) {
						sb.append(i18nKey);
						sb.append(Constants.EQUAL_SYMBOL);
						sb.append(Native2AsciiUtils.native2Ascii(enVal));
						sb.append(Constants.ENTER_SYMBOL);
					}
				}
			}
		} else {
			StringBuilder sb = sbMap.get(Constants.LOCALE[0]);
			if(null!=sb) {
				sb.append(i18nKey);
				sb.append(Constants.EQUAL_SYMBOL);
				sb.append(Native2AsciiUtils.native2Ascii(defaultCaption));
				sb.append(Constants.ENTER_SYMBOL);
			}
		}
	}
	
	/**
	 * 添加国际化资源app版
	 * 
	 * @param sbMap
	 * @param lgText
	 * @param i18nKey
	 * @param defaultCaption 中文名称
	 */
	public static void appendI18nMap(Map<String, Map<String,String>> mm, String lgText, String i18nKey, String defaultCaption) {
		if(StringUtils.isNotBlank(lgText)) {
			Map<String, String> map = jsonBinder.fromJson(lgText, HashMap.class);
			for(Map.Entry<String, String> entry : map.entrySet()) {
				String enKey = entry.getKey();
				String enVal = entry.getValue();
				if(StringUtils.isNotBlank(enKey) && StringUtils.isNotBlank(enVal)) {
					Map<String, String> sMap = mm.get(enKey);
					if(null!=sMap) {
						sMap.put(i18nKey,enVal);
					}
				}
			}
		} else {
			Map<String, String> sMap = mm.get(Constants.LOCALE[0]);
			if(null!=sMap) {
				sMap.put(i18nKey, defaultCaption);
			}
		}
	}
	
	
	/**
	 * 清理tomcat缓存，用于国际资源重载
	 */
	private static void clearTomcatCache() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        // no need for compilation here.
        Class cl = loader.getClass();

        try {
            if ("org.apache.catalina.loader.WebappClassLoader".equals(cl.getName())) {
                clearMap(cl, loader, TOMCAT_RESOURCE_ENTRIES_FIELD);
            }
        } catch (NoSuchFieldException nsfe) {
            if ("org.apache.catalina.loader.WebappClassLoaderBase".equals(cl.getSuperclass().getName())) {
                try {
                    clearMap(cl.getSuperclass(), loader, TOMCAT_RESOURCE_ENTRIES_FIELD);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 清理Map缓存
     * 
     * @param cl
     * @param obj
     * @param name
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    private static void clearMap(Class cl, Object obj, String name)
            throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        java.lang.reflect.Field field = cl.getDeclaredField(name);
        field.setAccessible(true);

        Object cache = field.get(obj);

        synchronized (cache) {
            Class ccl = cache.getClass();
            Method clearMethod = ccl.getMethod("clear");
            clearMethod.invoke(cache);
        }
    }
    
    /**
     * jwp解析后续步骤：部署流程文件--生成菜单资源--生成默认配置--复制配置至应用目录--生成唯一版本文件
     * 
     * @param filePath
     * @param packagePath
     * @param gp
	 * @param jwpPathName
     */
    private static String doSwitchFile(String filePath, String packagePath, GsPackage gp, Boolean isFullUpdate, List<String> updatedModules ,String  jwpPathName) {
    	try {
			deployFlow(filePath, isFullUpdate, updatedModules);
		} catch (Exception e6) {
			throw new GscException("自动部署流程文件出现异常", e6);
		}
		String jwpName = "";
		String  jsversion= jwpPathName.substring(4,14);
		try {
			jwpName = generateMenu(filePath, gp, isFullUpdate, updatedModules,jsversion);
		} catch (Exception e5) {
			throw new GscException("自动生成菜单资源出现异常", e5);
		}
		String defaultDir = concat(packagePath, Constants.DEFAULT_CONFIG_FILE);
		try {
			doCopyFileToDefaultConfigDir(filePath, defaultDir, isFullUpdate);
		} catch (Exception e9) {
			throw new GscException("复制文件至默认配置目录出现异常", e9);
		}
		try {
			//复制i18n资源文件
			doCopyI18nFileToAppDir(defaultDir, isFullUpdate);
			//复制所有jsp文件至应用目录
			doCopyJspFileToAppDir(defaultDir, isFullUpdate);
			//更新移动端
			doCopyMobileFileToAppDir(defaultDir,isFullUpdate,jsversion);
		} catch (Exception e6) {
			throw new GscException("复制默认配置文件至应用目录出现异常", e6);
		}

		//生成版本文件
		generateVersionFile(packagePath);
		return jwpName;
    }
    
    /**
     * 检查jwp版本号
     * 
     * @param jwpPathName
     * @param file
     * @return
     */
    public static boolean checkJwpVersion(String jwpPathName, File file, String fileName) {
    	String packagePath = concat(sp.getUploadFilePath(), Constants.GS_PACKAGE_PATH);
		String filePath = concat(packagePath, jwpPathName ,Constants.PATH_SEPARATOR);
		//filePath = filePath.replace("\\", "/");
		File destFile = new File(filePath+Constants.CONFIG_FILE_NAME);
		String jwpPath = filePath+Constants.CONFIG_FILE_NAME;
		try {
			FileUtils.copyFile(file, destFile);
		} catch (IOException e1) {
			throw new GscException(fileName + "文件移动出现异常", e1);
		}
		try {
			ZipUtils.unzip(jwpPath, filePath);
			
		} catch (Exception e2) {
			throw new GscException(fileName + "文件解压缩出现异常", e2);
		}
		
		String srcVersion = concat(filePath, Constants.VERSION_FILE_PATH);
		File srcVersionFile = new File(srcVersion);
		if(!srcVersionFile.exists()) {
			return true;
		}
		String destVersion = concat(packagePath, Constants.DEFAULT_VERSION_FILE_PATH);
		File destVersionFile = new File(destVersion);
		if(!destVersionFile.exists()) {
			return true;
		}
		String srcMd5 = Md5Utils.getMD5(srcVersionFile);
		String destMd5 = Md5Utils.getMD5(destVersionFile);
		if(srcMd5.equals(destMd5)) {
			return true;
		} else {
			return false;
		}
    }
    
	/**
	 * 解析GS包处理
	 * @param appPath 应用所在物理路径
	 */
	public static String handleGs(String jwpPathName, Boolean isFullUpdate) {
		String packagePath = concat(sp.getUploadFilePath(), Constants.GS_PACKAGE_PATH);
		String filePath = concat(packagePath, jwpPathName ,Constants.PATH_SEPARATOR);
		GsPackage gp = null;
		try {
			String configPath = concat(filePath, Constants.CONFIG_PATH);
			gp = parseGSFile(configPath);
		} catch (Exception e3) {
			throw new GscException(jwpPathName + "文件解析出现异常", e3);
		}
		List<TableEntitys> tesList = null;
		List<String> updatedModules = Lists.newArrayList();
		try {
			tesList = handleGSR(gp, filePath, isFullUpdate, updatedModules);
			//tesList = handleGS(gp, filePath);
		} catch (Exception e4) {
			throw new GscException(jwpPathName + "文件处理出现异常", e4);
		}
		try {
			handleTableEntitys(tesList, filePath);
		} catch (Exception e8) {
			throw new GscException(jwpPathName + "文件生成hbm及entity文件出现异常", e8);
		}
		String jwpName = doSwitchFile(filePath, packagePath, gp, isFullUpdate, updatedModules,jwpPathName);
		return jwpName;
	}
	
	/**
	 * 生成唯一版本文件
	 * 
	 * @param jwpPath
	 */
	private static void generateVersionFile(String packagePath) {
		String versionFile = concat(packagePath, Constants.DEFAULT_VERSION_FILE_PATH);
		UUID uuid = UUID.randomUUID();
		File file = new File(versionFile);
		try {
			FileUtils.writeByteArrayToFile(file, uuid.toString().getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
/*	*//**
	 * 切换jwp版本，用于回滚或升级
	 * 
	 * @param jwpPathName
	 *//*
	public static String switchJwpToVersion(String jwpPathName) {
		String packagePath = sp.getUploadFilePath() + Constants.GS_PACKAGE_PATH;
		String jwpPath = concat(packagePath, jwpPathName, Constants.PATH_SEPARATOR);
		GsPackage gp = null;
		String configPath = concat(jwpPath, Constants.CONFIG_PATH, Constants.MODULE_PATH);
		try {
			gp = parseGSFile(configPath);
		} catch (Exception e3) {
			throw new GscException(configPath + "目录解析出现异常", e3);
		}
		loadHbmEntity(jwpPath);
		String jwpName = doSwitchFile(jwpPath, packagePath, gp);
		return jwpName;
	}*/
	
	/**
	 * 获取异常堆栈消息
	 * 
	 * @param e
	 * @return
	 */
	public static String getStackTrace(Throwable e) {
		StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
	}

   public static   void  doCopyMobileFileToAppDir(String defaultDir,Boolean isFullUpdate,String  jsversion){

	   HttpServletRequest request =Struts2Utils.getRequest();
	   String  itemName = request.getContextPath();
	   //复制移动端i18n资源文件
	   doCopyI18nFileToMobileDir(defaultDir,itemName,isFullUpdate);
	   //复制所有vue文件至应用目录
	   doCopyVueFileToMobileDir(defaultDir,itemName,isFullUpdate);
	   //复制router.js到weex的src目录下
	   doCopyRouterFileToAppDir(defaultDir,itemName);
	   //复制weexplus.json到weex的configs目录下
	   doCopyWeexplusFileToAppDir(defaultDir);

	   //移动端打包
	   updateJsversion(jsversion);
   }

   public static void  updateJsversion(String  jsversion){
	   final String  batPath =	sp.getHotUpdateBatPath();
	   if(!StringUtils.isBlank(batPath)) {
		   HttpServletRequest request = Struts2Utils.getRequest();
		   final String jsvs = jsversion;
		   final String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/updater/updateJsversoin.do";
		   final String downloadUrl = "/iMobile/app.zip";
		   asyncServicePool.execute(new Runnable() {
			   @Override
			   public void run() {
				   try {
					   //调用移动端打包脚本
					   //执行打热更新包的脚本
					   CallBat.callCmd(batPath);

					   //更新移动端版本信息
					   Map<String, String> map = new HashMap<>();
					   map.put("jsversion", jsvs);
					   map.put("url", downloadUrl);
					   HttpClientUtils.post(url, map, "UTF-8");

				   } catch (Exception e) {
					   logger.error("执行异步打包时出现异常", e);
				   }
			   }
		   });
	   }
   }
}
